package com.xunfang.portal.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xunfang.common.RedisConst;
import com.xunfang.common.enumeration.UserStatus;
import com.xunfang.common.enumeration.impl.BusinessCode;
import com.xunfang.common.exception.Assert;
import com.xunfang.portal.model.entity.User;
import com.xunfang.portal.model.request.LoginRequest;
import com.xunfang.portal.model.vo.UserVo;
import com.xunfang.portal.service.UserService;
import com.xunfang.portal.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Objects;

/**
* @author scott
* @description 针对表【t_user】的数据库操作Service实现
* @createDate 2025-10-13 11:22:31
*/
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public ResponseEntity<?> login(LoginRequest param) {

        //判断验证码
        String key = param.getKey();
        String redisCode = stringRedisTemplate.opsForValue().get(key);

        //判断验证码是否过期
        Assert.error(!StringUtils.hasText(redisCode), BusinessCode.INVALID_VERIFICATION);

        //判断验证码是合法
        Assert.error(!redisCode.equalsIgnoreCase(param.getCode()), BusinessCode.VERIFICATION_ERROR);
        //01
        //判断用户是否存在
        String account = param.getAccount();

        LambdaQueryWrapper<User> userLambdaQueryWrapper = Wrappers.lambdaQuery(User.class).eq(User::getAccount, account);
        User user = getOne(userLambdaQueryWrapper);

        //判断用户是否存在
        Assert.error(Objects.isNull(user), BusinessCode.USER_NOT_EXIST);

        //判断 密码
        //明文密码   1234                 页面
        //加密密码   $2a$10$uaLcTE8sru237EEgEzv.FOZ1/H1Z4VkxXTWnekqMFk2Gbh/kRyuNa   数据库
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        boolean matches = encoder.matches(param.getPassword(), user.getPassword());
        Assert.error(!matches, BusinessCode.PASSWORD_ERROR);
        //判断是否 用户 激活
        Assert.error(user.getState() != UserStatus.ACTIVE.getKey(), BusinessCode.USER_FROZEN_ERROR);

        return ResponseEntity.ok(user);
    }

    /**
     * 通过id 查询用户
     * @param id
     * @return
     */
    @Override
    @Cacheable(cacheNames = RedisConst.USER_DETAIL, keyGenerator = "keyGenerator")
    public UserVo findById(Long id) {

        //查询用户
        User user = getById(id);
        UserVo userVo = new UserVo();
        BeanUtil.copyProperties(user,userVo);

        return userVo;
    }

    @Override
    public User findByMobile(String telephone) {

        User user = getOne(Wrappers.lambdaQuery(User.class).eq(User::getMobile, telephone));

        return user;

    }

    /**
     *  用户存在 邮件已存在
     * @param email
     * @return
     */
    @Override
    public boolean isEmailExist(String email) {

        User user = getOne(Wrappers.lambdaQuery(User.class).eq(User::getEmail, email));

        return Objects.nonNull(user);
    }

    @Override
    public boolean isAccountExist(String account) {
        User user = getOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getAccount, account));
        return Objects.nonNull(user);
    }

    @Override
    public boolean isMobileExist(String mobile) {
        User user = getOne(Wrappers.lambdaQuery(User.class)
                .eq(User::getMobile, mobile));
        return Objects.nonNull(user);
    }

    @Override
    public User register(User user) {
        //对密码进行加密
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        //设置用户状态
        user.setState(UserStatus.ACTIVE.getKey());
        //写入数据库，会自动更新user的id值
        save(user);
        return user;
    }

}




